<?php

$loader->requireOnce('includes/MimeLookup.class.php');

/**
 * class Document
 * This class is the logical representation of a physical file on some system somewhere that can be referenced with a URL
 * of some type. This URL is not necessarily a web url, it could be a file URL or reference to a BLOB in a db.
 * It is implicit that a document can have other related tables to it at least a one document to many notes which join on a documents 
 * id and categories which do the same. 
 */
 
class Document extends ORDataObject{
	
	/*
	*	Database unique identifier
	*	@var id
	*/
	var $document_id = '';
	var $document_store_id = '';
	var $created = '';
	var $maxX = 300;
	var $maxY = 300;
	var $thumnail_url = '';
	var $location = '';
	
	/*
	*	DB unique identifier reference to some other table, this is not unique in the document table
	*	@var int
	*/
	var $foreign_id = '';
	
	/*
	*	Enumerated DB field which is met information about how to use the URL
	*	@var int can also be a the properly enumerated string
	*/
	var $type;
	
	/*
	*	Array mapping of possible for values for the type variable
	*	mapping is array text name to index
	*	@var array
	*/
	var $type_array = array();
	
	/*
	*	Size of the document in bytes if that is available
	*	@var int
	*/
	var $size;
	
	/*
	*	Date the document was first persisted
	*	@var string
	*/
	var $date;
	
	/*
	*	URL which point to the document, may be a file URL, a web URL, a db BLOB URL, or others
	*	@var string
	*/
	var $url;
	
	/*
	*	Mimetype of the document if available
	*	@var string
	*/
	var $mimetype;
	/**
	 * Display name, if not will be set to basename fileurl on get
	 */
	var $name = "";
	var $_table = 'document';
	var $_key = 'document_id';
	var $_internalName='Document';
	var $base = 'user/documents/';
	var $baseUrl = '';
		
	/**
	 * Constructor sets all Document attributes to their default value
	 * @param int $id optional existing id of a specific document, if omitted a "blank" document is created 
	 */
	function Document($id = "")	{
		//call the parent constructor so we have a _db to work with
		parent::ORDataObject();
		//shore up the most basic ORDataObject bits
		$this->id = $id;
		//load the enum type from the db using the parent helper function, this uses psuedo-class variables so it is really cheap
		$this->type_array = $this->_load_enum("type");
		$tmp = array_flip($this->type_array);
		
		$this->type = $tmp[0];
		$this->size = 0;
		$this->date = date("Y-m-d H:i:s");
		$this->url = "";
		$this->mimetype = "";		
		
		if ($id != "") {
			$this->populate();
		}
	}
	
	function addNewDocument($patientID, $storeID, $file, $fitToFrame=false){
		$link = Celini::link('viewDocument', 'Document');		
		$this->baseUrl = "http://".$_SERVER['SERVER_NAME'].":".$_SERVER['SERVER_PORT']."/".strtok($link,'/')."/".$this->base;
		$search = array('-',' ',':');
		$replace = array('','','');
		$newFileName = str_replace($search, $replace, $this->date);
		// Create a folder for patient if it is not available
		$dir = $_SERVER['DOCUMENT_ROOT'] . Celini::getBaseDir() . $this->base . $patientID;
		if(!is_dir($dir)){
			mkdir($dir, 0777);
			chmod($dir, 0777);
		}			
		// Copy thumnail image to folder of thumnail
		$thumDir = $dir . "/Thumnail/";
		$thumnail = $this->createThumnail($file['type'], strtolower($file['name']), strtolower($file['tmp_name']), $this->maxX, $this->maxY, $fitToFrame);
		if(!is_dir($thumDir)){
			mkdir($thumDir, 0777);
			chmod($thumDir, 0777);
		}		
		
		if($file['type'] == 'image/jpeg' || $file['type'] == 'image/pjpeg') imagejpeg($thumnail, $thumDir.time() . '_' .$file['name'], 100);
		elseif($file['type'] == "image/png" || $file['type'] == 'image/x-png') imagepng($thumnail, $thumDir.time() . '_' .$file['name'], 9);
		elseif($file['type'] == "image/gif") imagegif($thumnail, $thumDir.time() . '_' .$file['name']);		
		// Copy full image to folder of patient
		$fullDir = $dir . "/Full/";
		if(!is_dir($fullDir)){
			mkdir($fullDir, 0777);
			chmod($fullDir, 0777);
		}
		move_uploaded_file($file['tmp_name'], $fullDir .time() . '_' .$file['name']);		

		$data = array (
				'document_store_id' => $storeID,
				'name'				=> $file['name'],
				'url'				=> $this->baseUrl.$patientID."/Full/".time() . '_' .$file['name'],
				'thumnail_url'		=> $this->baseUrl.$patientID."/Thumnail/".time() . '_' .$file['name'],
				'type'				=> "web_url",
				'mimetype'			=> $file['type'],
				'size'				=> $file['size'],
				'location'			=> $fullDir .time() . '_' .$file['name']
			);
		$this->populateArray($data);		
		$this->persist();		
		$sql = "UPDATE document SET created = NOW() WHERE document_id = $this->document_id";
		$this->_execute($sql);	
				
		return $this->document_id;			
	}
	
	function createThumnail($type, $filename, $tmpname, $xmax, $ymax, $fitToFrame=false){
		switch ($type){
			case "image/jpeg":
				$im = imagecreatefromjpeg($tmpname);
				break;
			case "image/pjpeg":
				$im = imagecreatefromjpeg($tmpname);
				break;			
			case "image/png":
				$im = imagecreatefrompng($tmpname);
				break;
			case "image/x-png":
				$im = imagecreatefrompng($tmpname);
				break;				
			case "image/gif":
				$im = imagecreatefromgif($tmpname);
				break;
		}
		$x = imagesx($im);
		$y = imagesy($im);
		if($x <= $xmax && $y <= $ymax) return $im;
		if(!$fitToFrame){
			if($x >= $y) {
				$newx = $xmax;
				$newy = $newx * $y / $x;
			} else {
				$newy = $ymax;
				$newx = $x / $y * $newy;
			}
		}
		else{
			$ratio	=	min(array($xmax/$x,$ymax/$y));
			$newx	=	$ratio*$x;
			$newy	=	$ratio*$y;
		}
		$im2 = imagecreatetruecolor($newx, $newy);
		imagecopyresized($im2, $im, 0, 0, 0, 0, floor($newx), floor($newy), $x, $y);
		return $im2;
	}
	
	function removeDocument($documentId){
		// Remove file containing full image from user/Document/	
		$ds = new Datasource_sql();
		$sql = array(
			'cols'	=> "location",
			'from'	=> "document",
			'where'	=> "document_id = '$documentId'"
		);
		$ds->setup($this->_db, $sql);
		$result = $ds->toArray();
		if (empty($result)) return "File không tồn tại";
		else {
			unlink($result[0]['location']);	
			// Remove file containing thumbnail
			unlink(str_replace('Full', 'Thumnail', $result[0]['location']));
		}					
		
		$sql = "DELETE FROM document WHERE document_id = '".$documentId."'";
		$this->_execute($sql);
	}
	
	function getStoreID($recordID){
		$ds = new Datasource_sql();
		$sql = array(
			'cols' 		=> "document_store_id",
			'from' 		=> "document_store",
			'where' 	=> "medical_record_id = '$recordID'"
			);
					
		$ds->setup($this->_db,$sql);
		$result = $ds->toArray('document_store_id');

		if (empty($result)){
			// If there is no document_store_id associated with this record, create one
			$newStore = Celini::newORDO('DocumentStore');	
			$storeID = $newStore->addNewDocumentStore($recordID);			
		} else $storeID = $result[0];
		return $storeID;		
	}
	
	function getDocuments($storeID, $count=''){
		$format	=	L10nHelper::getSqlDateFormat('YmdHi');
		if ($count == '') $count = 30;
		$ds = new Datasource_sql();
		$sql = array(
			'cols' 		=> "document_id, name, DATE_FORMAT(created, '$format') as created, type, url, thumnail_url, size, mimetype",
			'from' 		=> "document",
			'where' 	=> "document_store_id = $storeID", 			
			'orderby' 	=> "created desc",
			'limit'		=> $count
			);
	
		$ds->setup($this->_db,$sql);	
		return $ds->toArray();	
	}
	
	function getDocument($docID){
		$format	=	L10nHelper::getSqlDateFormat('YmdHi');
		$ds = new Datasource_sql();
		$sql = array(
			'cols' 		=> "document_id, name, DATE_FORMAT(created, '$format') as created , type, url, thumnail_url, size, mimetype",
			'from' 		=> "document",
			'where' 	=> "document_id = $docID"
			);
	
		$ds->setup($this->_db,$sql);	
		$result = $ds->toArray();
		return $result[0];
	}	
	
	function getName($documentID){
		$ds = new Datasource_sql();
		$sql = array(
			'cols' 		=> "name",
			'from' 		=> "document",
			'where' 	=> "(document_id = '$documentID')"
			);
	
		$ds->setup($this->_db,$sql);	
		$result = $ds->toArray();		
		return $result[0]['name'];		
	}
	
	function setName($name, $documentID){
		$update = "UPDATE document SET name = '$name' WHERE (document_id = $documentID)";
		$this->_execute($update);		
	}
	
	function persist($fid ="") {
		if (!empty($fid)) {
			$this->foreign_id = $fid;
		}
		parent::persist();
	}
	
	public function setMaxX($value){
		$this->maxX	=	$value; 
	}
	
	public function setMaxY($value){
		$this->maxY	=	$value; 
	}
	
	public function deleteDocuments($storeId){
		$sql	=	"DELETE FROM $this->_table WHERE document_store_id=".(int)$storeId;
  		$res	=	$this->_execute($sql);
  		return $res;
	}
} // end of Document
?>
